#ifndef __APX5200SA_H__
#define __APX5200SA_H__

#ifndef _WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif

//#ifdef APX5200SA_DLL
//#define APX5200SA_DLL __declspec(dllexport)
//#endif
#ifndef APX5200SA_DLL
#define APX5200SA_DLL __declspec(dllimport)
#endif


enum
{
	APX5200_STATUS_NOT_FILEOPEN = -21001,
	/** Error	: File Open Error*/
	APX5200_STATUS_NOT_SET_PARAM = -21002,
	/** Error	: Necessary parameter is not set.*/
	APX5200_STATUS_NOT_ENOUGH_PARAM = -21003,
	/** Error	: There are not enough parameters for the read file.*/
	APX5200_STATUS_UNPREPARED_SCAN = -21004,
	/** Error	: Has not configured scan setting*/
	APX5200_STATUS_CNAT_SET_AOBUFFER = -21005,
	/** Error	: Can't set ao buffer because of trace data size over*/
	APX5200_STATUS_POSITION_OVERRANGE = -21006,
	/** Error	: Specified position is out of valid range */
	APX5200_STATUS_VOLTAGE_OVERRANGE = -21007,
	/** Error	: Convered ao value is out of valid range  */
	APX5200_STATUS_ERR_MEM_COPY = -21008,
	/** Error	: Error has occured when data copy  */
	APX5200_STATUS_ERR_MEM_ALLOC = -21009,
	/** Error	: Memory allocation failed*/
	APX5200_STATUS_ERR_ARRAY_SIZE = -21010,
	/** Error	: Lack of the array size*/
	APX5200_STATUS_UNMATCH_CAP_SIZE = -21011,
	/** Error	: The actual and excepted capture deta  size is not matched.
																	   It is possible that it has not been started by 'apx5200saStartBscan' */
	APX5200_STATUS_ERR_AO_ARRAY_SIZE = -21012,
	/** Error	: Insufficient AO buffer size */
	APX5200_STATUS_ERR_RETURNED_NULL = -21013,
	/** Error	: apx5200saWaitSampling returned pBuffer address is null.
																	 It is possible that acquisition settings have any problems.*/
	APX5200_STATUS_ARRAY_ORDER_ILLEGAL = -21014,
	/** Error	: The sequence order of Window and Theta is incorrect.*/
	APX5200_STATUS_INVALID_CAPTURENUM = -21015,
	/** Error	: CaptureNum is not set to an even value.*/
	APX5200_STATUS_UNEXECUTED_FUNCTION = -21016,	/** Error	: A mandatory function has not been executed.*/
	APX5200_STATUS_EXCESSIVE_SPEED = -21017,	/** Error	: The speed is too fast.*/
    APX5200_STATUS_INCOMPATI_FPGA_VER =  -20024   /** Error  : Cant execute that function due to incompatible of FPGA version */
	

};

#ifndef __APX5200_H__
// apend error
#define APX5200_STATUS_SUCCESS                 0	/** Info   : Operation was successful; No error occurred. */
#define APX5200_STATUS_ERROR               -1001	/** Error  : Unspecified runtime error. */
#define APX5200_STATUS_NOT_INITIALIZED     -1002	/** Error  : Module not initialized; e.g. An initialize method was not called before handling, or cannot establish a connection between devices(a frame grabber and a camera). */
#define APX5200_STATUS_NOT_IMPLEMENTED     -1003	/** Error  : Requested operation not implemented; e.g. No supported event or has no functions on a buffer module. */
#define APX5200_STATUS_RESOURCE_IN_USE     -1004	/** Warn   : Requested resource is already in use by another operator. Requested operation is not allowed; e.g. a remote device is opened by another client. */
#define APX5200_STATUS_ACCESS_DENIED       -1005	/** Warn   : Requested operation is not allowed; e.g. a remote device is opened by another client. */
#define APX5200_STATUS_INVALID_HANDLE      -1006	/** Error  : Given handle does not support the operation; e.g. function call on wrong handle or NULL pointer. */
#define APX5200_STATUS_INVALID_ID          -1007	/** Error  : ID could not be connected to a resource; e.g. a device with the given ID is currently not available. */
#define APX5200_STATUS_NO_DATA             -1008	/** Error  : The function has no data to work on. */
#define APX5200_STATUS_INVALID_PARAMETER   -1009	/** Error  : One of the parameter given was not valid or out of range and none of the error codes above fits. */
#define APX5200_STATUS_IO                  -1010	/** Error  : Communication error has occurred; e.g., A read and/or write operation to a remote device is failed.  Or To access to the physical module 'PCI'. */
#define APX5200_STATUS_TIMEOUT             -1011	/** Warn   : An operation�fs timeout time period expired before it could be completed. */
#define APX5200_STATUS_ABORT               -1012	/** Info   : An operation has been aborted before it could be completed. For example a wait operation through a waiting any event. */
#define APX5200_STATUS_INVALID_BUFFER      -1013	/** Error  : No buffer announced for an acquisition or one or more buffers of the acquisition with invalid buffer size. */
#define APX5200_STATUS_NOT_AVAILABLE       -1014	/** Warn   : Resource or information is not available at a given time in a current state. */
#define APX5200_STATUS_INVALID_ADDRESS     -1015	/** Error  : A given address is out of range or invalid for internal reasons. */

#define APX5200_STATUS_CUSTOM_ID           -10000	/** Error  : Any error smaller or equal than -10000 is implementation specific. If a Consumer application receives such an error number it should react as if it would be a generic runtime error. */

#define APX5200_STATUS_CONNECT_LOST        -20001	/** Warn   : A connection is lost.  e.g., a physical cable plug-off, or stopped supply a power with a camera device*/
#define APX5200_STATUS_SHORTAGE_RESOURCE   -20002	/** Warn   : A resources is shorgate.  e.g., a physical continuas , remapping memory, an image buffer, a FIFO memory or a stortage.*/
#define APX5200_STATUS_OUT_OF_RANGE        -20003	/** Error  : One, or some parameter(s) was out of range . the parameter(s) exceeded by max or less than min. */
#define APX5200_STATUS_INVALID_XFER        -20004	/** Error  : the transfer parameters(DMA script, buffer address/list and the size of an image) for an acquisition is invalid. */
#define APX5200_STATUS_UNABLE_READ         -20005	/** Error  : Reading error has occurred; e.g., A read operation to a remote(e.g., Camera) or a local device(e.g., PCI) is failed.  */
#define APX5200_STATUS_UNABLE_WRITE        -20006	/** Error  : Writing error has occurred; e.g., A write operation to a remote(e.g., Camera) or a local device(e.g., PCI) is failed.  */
#define APX5200_STATUS_NOT_NOTIFIED        -20007	/** Error  : Announce or receive events error has occurred; e.g., Notification (e.g., the end of frame, interrupt GPIN or received message ) to a user is failed.  */

#define APX5200_STATUS_UNABLE_ALLOCATE     -20008	/** Error  : Allocation error related to the resource, handle, or array. */
#define APX5200_STATUS_IN_PROGRESS         -20009	/** Error  : Requested operation already in progress */
#define APX5200_STATUS_NOT_EXCLUSIVE       -20010	/** Error  : Exclusive error */

#define APX5200_STATUS_INVALID_REQUEST	   -20011	/** Error  : Invalid Request Error */
#define APX5200_STATUS_NO_TARGET_BOARD	   -20012	/** Error  : No Target Board */
#define APX5200_STATUS_ALREADY_SAMPLING	   -20013	/** Error  : Already Sampling */
#define APX5200_STATUS_ALREADY_AO_OUTPUT   -20014	/** Error  : Already Ao Output */
#define APX5200_STATUS_PLL_NOT_SUPPORT	   -20015	/** Error  : PLL Not Support Clock  */
#define APX5200_STATUS_CLOCK_UNSTABLE	   -20016	/** Error  : PLL Clock Unstatabule*/
#define APX5200_STATUS_ABNORMAL			   -20017	/** Error  : Sampling Error Abnormal */
#define APX5200_STATUS_SAMPLING_STOPPED    -20018	/** Error  : Sampling DMA Already Stopped */
#define APX5200_STATUS_HW_DAMAGES          -20019	/** Error  : Hard Ware Temperature Over */
#define APX5200_STATUS_MEM_FREE_ERROR      -20020   /** Error  : DMA Memory Free Error */
#define APX5200_STATUS_NO_SET_BUFFER       -20021   /** Error  : Not Set Buffer Error */
#define APX5200_STATUS_INVALID_INDEX       -20022   /** Error  : Select Index Invalid Error */
#define APX5200_STATUS_AO_BUFFSET_ERROR    -20023   /** Error  : AO Buffer Setting Error */


//***********************************************************************************
// H/W Information
//
typedef struct _ADC5200_BD_INF
{
	int				admType;				// ADM Board Type
	int				chNum;					// Channel Number
	int				aoNum;					// Ao Number
	int				doNum;					// DO Number
	int				diNum;					// DI Number
	int				minClock;				// Min Sampling Clock
	int				maxClock;				// Max Sampling Clock
	int				bit;					// Data Bit Length
	int				packSize;				// 1Package Size [Byte]
	int				DipSW;					// Dip Switch
	unsigned int	DDRSize;				// DDR Size [MByte]
	unsigned int	ApxVer;					// APX-5000 FPGA Version
	unsigned int	drvVer;					// Driver Version
	unsigned int	libVer;					// Library Version
	unsigned int	boardID;				// Board ID
} ADC5200_BD_INF, *PADC5200_BD_INF;

// admType
#define ADM_TYPE_5200						(4)
#define ADM_TYPE_5200A						(5)
#define ADM_TYPE_5360						(6)
#define ADM_TYPE_5360G3						(7)

//***********************************************************************************
// Input Signal
//
// VoltageRange
#define ADC5200_INP_VOLTAGERANGE_500MV		(500)
#define ADC5200_INP_VOLTAGERANGE_MAX		(ADC5200_INP_VOLTAGERANGE_500MV)
#define ADC5200_RAW_TO_MV(adm, d)	(																				\
	((adm == ADM_TYPE_5200) || (adm == ADM_TYPE_5360) || (adm == ADM_TYPE_5200A) || (adm == ADM_TYPE_5360G3) 		\
		? (double)((((double)(d) - (double)(0x800)) * (double)(500)) / (double)(0x800))								\
	: 0 )																											\
	)

#define ADC5200_AO_MV_TO_RAW(mV) (unsigned short)((mV * (double)0x8000 / (double)5000) + (double)0x8000)

// Size
#define ADC5200_INP_SIZE_MIN				(512)


//***********************************************************************************
// Board Param Information
#define ADC5200_INTERLEAVING_DISABLE		(0)
#define ADC5200_INTERLEAVING_ENABLE			(1)

//***********************************************************************************
// Clock Information
//
// Clock Source
#define ADC5200_CLOCKSOURCE_DISABLE			(0)
#define ADC5200_CLOCKSOURCE_ONBOARD			(1)		// Onboard Clock
#define ADC5200_CLOCKSOURCE_EXTCLOCK		(2)		// Ext. Clock
#define ADC5200_CLOCKSOURCE_EXT_DIRECT		(3)		// Ext. Clock    <Sampling clock direct connect> ��Input only
#define ADC5200_CLOCKSOURCE_NO_SUPPORT		(-1)

//***********************************************************************************
// Trigger Information
//

// Input Trigger Signal Edge
#define ADC5200_TRIG_INPUT_EDGE_RISE		(0)
#define ADC5200_TRIG_INPUT_EDGE_FALL		(1)

// Trigger Mask
#define ADC5200_DI_MASK_DISABLE		(0)
#define ADC5200_DI_MASK_DI0			(1)
#define ADC5200_DI_MASK_DI1			(2)
#define ADC5200_DI_MASK_DI2			(4)
#define ADC5200_DI_MASK_DI3			(8)
#define ADC5200_DI_MASK_ALL			(ADC5200_DI_MASK_DI0 | ADC5200_DI_MASK_DI1 | ADC5200_DI_MASK_DI2 | ADC5200_DI_MASK_DI3)

//***********************************************************************************
// Trigger Condition
//
typedef struct {
	unsigned int	Type;					// Type(Edge,Pulse)
	float			Threshold;				// Threshold Voltage
	float			PulseHigh;				// High limit
	float			PulseLow;				// Low limit
	int				Pulse;					// Pulse width
	int				SubPulse;				// SubPulse width
} ADC5200_TRG_CND;

// Type - Edge
#define ADC5200_TRG_CND_TRGTYPE_EDGE					(0x00)
#define ADC5200_TRG_CND_TRGTYPE_EDGE_LOW_TO_HIGH		(ADC5200_TRG_CND_TRGTYPE_EDGE | 0x00)
#define ADC5200_TRG_CND_TRGTYPE_EDGE_HIGH_TO_LOW		(ADC5200_TRG_CND_TRGTYPE_EDGE | 0x02)
#define ADC5200_TRG_CND_TRGTYPE_EDGE_MOVE_LOW_HIGH		(ADC5200_TRG_CND_TRGTYPE_EDGE | 0x08)

// Type - Pulse
#define ADC5200_TRG_CND_TRGTYPE_PULSE					(0x10)
#define ADC5200_TRG_CND_TRGTYPE_PULSE_MID_SHORT			(ADC5200_TRG_CND_TRGTYPE_PULSE | 0x02)
#define ADC5200_TRG_CND_TRGTYPE_PULSE_MID_LONG			(ADC5200_TRG_CND_TRGTYPE_PULSE | 0x03)

// Type
#define ADC5200_TRG_CND_TRGTYPE_EDGE_MIN				(ADC5200_TRG_CND_TRGTYPE_EDGE_LOW_TO_HIGH)
#define ADC5200_TRG_CND_TRGTYPE_EDGE_MAX				(ADC5200_TRG_CND_TRGTYPE_EDGE_MOVE_MID_OTHER)
#define ADC5200_TRG_CND_TRGTYPE_PULSE_MIN				(ADC5200_TRG_CND_TRGTYPE_PULSE_LOW_SHORT)
#define ADC5200_TRG_CND_TRGTYPE_PULSE_MAX				(ADC5200_TRG_CND_TRGTYPE_PULSE_HIGH_LONG)
	
// Pulse
#define ADC5200_TRG_CND_PULSE_MIN						(1)
#define ADC5200_TRG_CND_PULSE_MAX						(65520)  //due to  H/W limitation up to 0xFFEF

//***********************************************************************************
// Trigger Action
//
#ifndef __APX5200_H__
typedef struct
{
	int						Loop;					// invalied trigger number
	int                     DIMask;					// Trigger DI Mask
	long long				Offset;					// Trigger start position
} ADC5200_TRG_ACT, *PADC5200_TRG_ACT;
#endif

// Loop
#define ADC5200_TRG_ACT_LOOP_MIN			(1)
#define ADC5200_TRG_ACT_LOOP_MAX			(256)

//***********************************************************************************
// Trigger Group Information
//
typedef struct
{
	int					Source;				// Trigger Source Type(Input Signal,synch another channel, external trigger)
	ADC5200_TRG_ACT		Action;
	ADC5200_TRG_CND		Condition;			// enabled Only 'Trigger Source Type = Input Signal'
} ADC5200_TRG, *PADC5200_TRG,APX5200SA_TRG,*PAPX5200SA_TRG;

// Source
#define ADC5200_TRG_SOURCE_SKIP				(0)
#define ADC5200_TRG_SOURCE_ANALOG			(1 << 0)
#define ADC5200_TRG_SOURCE_ANOTHER			(1 << 1)
#define ADC5200_TRG_SOURCE_EXT				(1 << 2)
#define ADC5200_TRG_SOURCE_SOFT				(1 << 3)
#define ADC5200_TRG_SUPPORT_SOURCE	( \
	ADC5200_TRG_SOURCE_SKIP			| \
	ADC5200_TRG_SOURCE_ANALOG		| \
	ADC5200_TRG_SOURCE_ANOTHER		| \
	ADC5200_TRG_SOURCE_SOFT			| \
	ADC5200_TRG_SOURCE_EXT			  \
	)

//***********************************************************************************
// Sampling Status Information
//
#define ADC5200_STATUS_OVER_RANGE	(1 << 0)   // A/D Signal Over Range
#define ADC5200_STATUS_OVER_WRITE	(1 << 1)   // FIFO Over Write ---> Capture Stop
#define ADC5200_STATUS_OVER_FLOW	(1 << 2)   // Buffer Over Flow
#define ADC5200_STATUS_PLL_UNLOCK	(1 << 16)  // PLL Unlocked
#define ADC5200_STATUS_AO1_ERROR	(1 << 17)  // AO CH1 Error
#define ADC5200_STATUS_AO2_ERROR	(1 << 18)  // AO CH2 Error

//***********************************************************************************
// DI/DO, Ext.Trigger
//
#define ADC5200_DO_MAX_VAL			(0xF)   // D0[3.0]
#define ADC5200_DI_ACTIVE_LEVEL		(0xF)   // DI[3.0] Active Level

//***********************************************************************************
// AO
//

#define ADC5200_AO_CH1  (1)
#define ADC5200_AO_CH2  (2)

typedef struct _AO_5200_PARAM
{
	unsigned int AoMode;
	unsigned int WaitCount;
	unsigned int Size;
	unsigned short* pAoData;
}AO_5200_PARAM, *PAO_5200_PARAM;

#define ADC5200_AO_MODE_FREERUN			(0)		// Free run
#define ADC5200_AO_MODE_EXT_TRIG		(1)		// Ext Trigger Sync
#define ADC5200_AO_MODE_SW_TRIG_CH1		(2)		// CH1 SW Trigger Sync
#define ADC5200_AO_MODE_SAMPLE_CH1		(3)		// CH1 Sampling End Sync
#define ADC5200_AO_MODE_SW_TRIG_CH2		(4)		// CH2 SW Trigger Sync
#define ADC5200_AO_MODE_SAMPLE_CH2		(5)		// CH2 Sampling End Sync

#define ADC5200_AO_TRIGMODE_SWTRIG		(1 << 3)
#define ADC5200_AO_TRIGMODE_EXTRIG		(1 << 2)
#define ADC5200_AO_TRIGMODE_ALL			(ADC5200_AO_TRIGMODE_SWTRIG | ADC5200_AO_TRIGMODE_EXTRIG)

//***********************************************************************************
// Mode
//
#define ADC5200_SMP_MODE_SEQUENCE			(0)
#define ADC5200_SMP_MODE_STREAM				(1)

#else
typedef ADC5200_TRG APX5200SA_TRG;
typedef PADC5200_TRG PAPX5200SA_TRG;

#endif /* __APX5200_H__ */

#define ADC5200_AO_SYNC_EXT				(0)
#define ADC5200_AO_SYNC_DIO				(1)

//***********************************************************************************
// Input Signal
//
typedef struct _APX5200SA_INP
{
	float VoltageOffset;			// volatage offset
	unsigned int CaptureNum;		// Samplig Capture Count
	unsigned int TotalNum;			// Samplig Total Count
}APX5200SA_INP,*PAPX5200SA_INP;

//***********************************************************************************
// Sampling Data Information
//
typedef struct _APX5200SA_DATA
{
	unsigned short* pBuffer;
	int SegmentSize;
	int Size;
	unsigned int last;
	unsigned int status;
}APX5200SA_DATA,*PAPX5200SA_DATA;

//***********************************************************************************
// Output Mode
//
#define ADC5200SA_OUTMODE_RAW	(0)
#define ADC5200SA_OUTMODE_RESMP	(1)
#define ADC5200SA_OUTMODE_FFT	(2)
#define ADC5200SA_OUTMODE_POWER	(3)
#define ADC5200SA_OUTMODE_LOG	(4)
// Ver.2.0.0
#define ADC5200SA_OUTMODE_FFT_HALF		(5)
#define ADC5200SA_OUTMODE_POWER_HALF	(6)
#define ADC5200SA_OUTMODE_LOG_HALF		(7)
#define ADC5200SA_OUTMODE_FFT_QUARTER	(8)
#define ADC5200SA_OUTMODE_POWER_QUARTER	(9)
#define ADC5200SA_OUTMODE_LOG_QUARTER	(10)

//***********************************************************************************
// FIR
//
#define ADC5200SA_FIR_DISABLE	(0)
#define ADC5200SA_FIR_ENABLE	(1)

//***********************************************************************************
// Re Sampling
//
#define ADC5200SA_RESAMPLING_DISABLE	(0)
#define ADC5200SA_RESAMPLING_ENABLE		(1)

//***********************************************************************************
// SyncSource
//
#define ADC5200SA_SYNC_SOURCE_EXTRG	(0)
#define ADC5200SA_SYNC_SOURCE_DIO	(1)
// SyncMode
#define ADC5200_SYNCMODE_DISABLE			(0)
#define ADC5200_SYNCMODE_ENABLE				(1)

//***********************************************************************************
// FPGA Mode (Ver.2.0.0)
//
#define ADC5200SA_NORMAL_MODE (0)
#define ADC5200SA_ROUND_TRIP_MODE (1)

//***********************************************************************************
// Dispersion Ex (Ver.2.0.0)
//
#define ADC5200SA_NORMAL_FUNC (0)
#define ADC5200SA_EXTEND_FUNC (1)

//***********************************************************************************
// Analog output control for scan
//
//Type of how to convert position to voltage
//v : voltage , p = point[mm]
enum HAD5200VConvert {
    VoltPerPosition = 0,  // v =  [multiply] p : multiply[V/mm]
    VoltPerDegree = 1,    // v = 180 / pi * [multiply] atan(p/[FocalLength]) : multiply[V/degree]
    CalibTable = 2         // Converted to voltage by a calibration table
};

enum class HAD5200BScanMode
{
	Normal =0,		//NormalScan
	Divide2 = 1,
	Divide4 = 2,
	Trapezoidal = 3, //Trapezoidal speed time
	Custom =8
	
};

enum class HAD5200CScanMode
{
	RasterXLine = 0,					//Raster scan.Scan line is x      
	RasterYLine =1,						//Raster scan.Scan line is y
	RasterXLineContinuous =2,			//Continuous raster scan.Scan line is x
	RasterYLineContinuous =3,			//Continuous raster scan.Scan line is y
	RasterXLineContinuous2 = 4,			//Continuous raster scan.Scan line is x Scan only when the slow axis moves in one direction
	RasterYLineContinuous2 = 5,			//Continuous raster scan.Scan line is y Scan only when the slow axis moves in one direction
	RasterXLineT = 6,					//Raster scan.Scan line is x. The backward of fast axis is controlled by trapezoidal speed control.
	RasterYLineT = 7,					//Raster scan.Scan line is y. The backward of fast axis is controlled by trapezoidal speed control.
	RasterXLineContinuousT = 8,			//Continuous raster scan.Scan line is x. The backward of fast axis is controlled by trapezoidal speed control.
	RasterYLineContinuousT = 9,			//Continuous raster scan.Scan line is y. The backward of fast axis is controlled by trapezoidal speed control.
	RasterXLineContinuous2T = 10,		//Continuous raster scan.Scan line is x Scan only when the slow axis moves in one direction. The backward of fast axis is controlled by trapezoidal speed control.
	RasterYLineContinuous2T = 11,		//Continuous raster scan.Scan line is y Scan only when the slow axis moves in one direction. The backward of fast axis is controlled by trapezoidal speed control.
	RoundTripXLineContinuous = 12,		//Round trip scan.Scan line is x
	RoundTripXLineContinuousT = 13,		//Round trip scan.Scan line is x. Trapezoidal speed control is applied between the outbound and return trips.
	RasterXLine_DIV2 = 16,				//Raster scan.Scan line is x      
	RasterYLine_DIV2 = 17,				//Raster scan.Scan line is y
	RasterXLineContinuous_DIV2 = 18,	//Continuous raster scan.Scan line is x
	RasterYLineContinuous_DIV2 = 19,	//Continuous raster scan.Scan line is y
	RasterXLine_DIV4 = 32,				//Raster scan.Scan line is x      
	RasterYLine_DIV4 = 33,				//Raster scan.Scan line is y
	RasterXLineContinuous_DIV4 = 34,	//Continuous raster scan.Scan line is x
	RasterYLineContinuous_DIV4 = 35		//Continuous raster scan.Scan line is y
};

struct HAD5200Axis
{
    double Coefficient = 1;    // Conversion factor of voltage to position or degree 
    double Max = 2;			   // Maximum range[mm]
    double Min = -2;		   // Minimum range[mm]
    double MaxSpeed = 40;           // Max speed[m/sec]
	double MaxAcceleration = 40000;     // Max acceleration[m/sec^2] *Reserved
    bool Reverse = false;      // The positive direction is from upper left to lower right
	double Offset = 0;		   //voltage offset[V]
};
struct HAD5200PositionSetting
{
    HAD5200VConvert ConvertType = VoltPerPosition;
    double FocalLength = 1.0;     // It's necessary if 'ConvertType' is 'VoltPerDegree' [mm] 
    double ScanRate = 1.0;        // swape speed [Hz]
    HAD5200Axis X = {};          // X axis
    HAD5200Axis Y = {};          // Y axis
	double MovementDelay =0; //Command position movement delay. Specify by the number of point   ver 2.0.0
};

struct HAD5200_2D
{
    float X;   // [mm] or [V]
    float Y;   // [mm] or [V]
};

struct HAD5200BscanSetting
{
	HAD5200BScanMode Mode = HAD5200BScanMode::Normal;
	HAD5200_2D Start={0,0};	//Stat position of B scan[mm] 
	HAD5200_2D End ={10,0};	//End position of B scan[mm]
	unsigned int PointNum=100;		//A-scan number included in B scan
	unsigned int TotalPointNumber = 0; //Total number of A-scan including back forward note:this value is set by 'apx5200saSetBscanSetting' function
	unsigned int DepthOffset = 0;	   //Offset from A-scan
	unsigned int ZLength = 0;			//Size of A-scan. If 0 is specified, ResamplingSize / 2 - ZOffset will is set 
};
struct HAD5200CscanSetting
{
	HAD5200CScanMode Mode = HAD5200CScanMode::RasterXLine;
	HAD5200_2D Start = { 0,0 };	//Stat position of C scan[mm] 
	HAD5200_2D End = { 10,10 };	//End position of C scan[mm]
	unsigned int XPointNum = 100;		//X-axis Ascan number
	unsigned int YPointNum = 100;		//Y-axis Ascan number
	unsigned int ZOffset=0;				//Offset from A-scan
	unsigned int ZLength = 0;			//Size of A-scan If 0 is specified, ResamplingSize /2 - ZOffset will is set 
	unsigned int TotalLinePointNumber = 0;	//Total number of A-scan including back forward note:this value is set by 'apx5200saSetCscanSetting' function
	unsigned int LineNumber = 0;			//Number of the scan lines 'apx5200saSetCscanSetting' function
	double SlowAxisBacklashOffsetPixel = 0.0;	//When Mode is RasterXLineContinuous or RasterYLineContinuous, specify the offset value to be applied to the return action. 
	double FastAxisBacklashOffsetPixel = 0.0;	//When Mode is RasterXLineContinuous2 or RasterYLineContinuous2, specify the offset value to be applied to the return action.
};

typedef struct _HAD5200_FPGA_INF
{
	char			ConfigName[4];	//FPGA configuration name
	unsigned int	Update;			//FPGA update date
	unsigned int    CompileVersion;	//FPGA compile version

} HAD5200_FPGA_INF;

#define APX5200_STATUS_INVALID_DELAY  (-21020)	/** Error	:MovementDelay value is over backward size */

#ifdef __cplusplus
extern "C" {
#endif
APX5200SA_DLL void WINAPI apx5200saGetVersion(unsigned int* pVersion);
APX5200SA_DLL int WINAPI apx5200saInitialize(void);
APX5200SA_DLL int WINAPI apx5200saFinalize(void);
APX5200SA_DLL int WINAPI apx5200saGetBoardInf(int nBoardIndex, PADC5200_BD_INF pInf);
APX5200SA_DLL int WINAPI apx5200saGetTemp(int nBoardIndex, int* pTemp, bool* pActive);
APX5200SA_DLL int WINAPI apx5200saSetBuffer(int nBoardIndex, int nChannel, unsigned int BankNum);
APX5200SA_DLL int WINAPI apx5200saGetBuffer(int nBoardIndex, int nChannel, unsigned long long* pSize, unsigned short** pBuffer);
APX5200SA_DLL int WINAPI apx5200saRemoveBuffer(int nBoardIndex, int nChannel);
APX5200SA_DLL int WINAPI apx5200saSetClock(int nBoardIndex, int nInputClock, unsigned int nClockMask);
APX5200SA_DLL int WINAPI apx5200saGetClock(int nBoardIndex, int* pInputClock, unsigned int* pClockMask);
APX5200SA_DLL int WINAPI apx5200saSetExtTrigger(int nBoardIndex, int nInputEdge, int nSyncMode);
APX5200SA_DLL int WINAPI apx5200saGetExtTrigger(int nBoardIndex, int* pInputEdge, int* pSyncMode);
APX5200SA_DLL int WINAPI apx5200saSetSamplingMode(int nBoardIndex, int nMode);
APX5200SA_DLL int WINAPI apx5200saGetSamplingMode(int nBoardIndex, int* pMode);
APX5200SA_DLL int WINAPI apx5200saSetBdParameter(int nBoardIndex, int nClock, int nInterleaving);
APX5200SA_DLL int WINAPI apx5200saGetBdParameter(int nBoardIndex, int* pClock, int* pInterleaving);
APX5200SA_DLL int WINAPI apx5200saSetChParameter(int nBoardIndex, int nChannel, PAPX5200SA_INP pInp, PAPX5200SA_TRG pTrigger);
APX5200SA_DLL int WINAPI apx5200saGetChParameter(int nBoardIndex, int nChannel, PAPX5200SA_INP pInp, PAPX5200SA_TRG pTrigger);
APX5200SA_DLL int WINAPI apx5200saStart(int nBoardIndex, int nChannel);
APX5200SA_DLL int WINAPI apx5200saStop(int nBoardIndex);
APX5200SA_DLL int WINAPI apx5200saWaitSampling(int nBoardIndex, int nChannel, PAPX5200SA_DATA pData, unsigned int uTimeout);
APX5200SA_DLL int WINAPI apx5200saSetOutputMode(int nBoardIndex, int nOutputMode);
APX5200SA_DLL int WINAPI apx5200saGetOutputMode(int nBoardIndex, int* pOutputMode);
APX5200SA_DLL int WINAPI apx5200saSetCaptureSize(int nBoardIndex, unsigned int nCaptureSize);
APX5200SA_DLL int WINAPI apx5200saGetCaptureSize(int nBoardIndex, unsigned int* pCaptureSize);

APX5200SA_DLL int WINAPI apx5200saSetFIREnable(int nBoardIndex, int nFIREnable);
APX5200SA_DLL int WINAPI apx5200saGetFIREnable(int nBoardIndex, int* FIREnable);
APX5200SA_DLL int WINAPI apx5200saSetFIRWindow(int nBoardIndex, double* FIRWindow);
APX5200SA_DLL int WINAPI apx5200saGetFIRWindow(int nBoardIndex, double* FIRWindow);

APX5200SA_DLL int WINAPI apx5200saSetCrossThreshold(int nBoardIndex, int nThreshold);
APX5200SA_DLL int WINAPI apx5200saGetCrossThreshold(int nBoardIndex, int* pThreshold);
APX5200SA_DLL int WINAPI apx5200saSetCrossPointSize(int nBoardIndex, int nCrossPointSize);
APX5200SA_DLL int WINAPI apx5200saGetCrossPointSize(int nBoardIndex, int* pCrossPointSize);

APX5200SA_DLL int WINAPI apx5200saSetResamplingEnable(int nBoardIndex, int nResamplingEnable);
APX5200SA_DLL int WINAPI apx5200saGetResamplingEnable(int nBoardIndex, int* pResamplingEnable);
APX5200SA_DLL int WINAPI apx5200saSetResamplingSize(int nBoardIndex, int nResamplingSize);
APX5200SA_DLL int WINAPI apx5200saGetResamplingSize(int nBoardIndex, int* pResamplingSize);
APX5200SA_DLL int WINAPI apx5200saSetResamplingDelay(int nBoardIndex, double Delay);
APX5200SA_DLL int WINAPI apx5200saGetResamplingDelay(int nBoardIndex, double* pDelay);

APX5200SA_DLL int WINAPI apx5200saSetWindowAndDispersion(int nBoardIndex, double* pWindow, double* pTheta);
APX5200SA_DLL int WINAPI apx5200saGetWindowAndDispersion(int nBoardIndex, double* pReal, double* pImage);

APX5200SA_DLL int WINAPI apx5200saSetAoParameter(int nBoardIndex, int nAoChannel, PAO_5200_PARAM pAoParam);
APX5200SA_DLL int WINAPI apx5200saGetAoParameter(int nBoardIndex, int nAoChannel, PAO_5200_PARAM pAoParam);
APX5200SA_DLL int WINAPI apx5200saSetSyncSource(int nBoardIndex, int nSyncSource);
APX5200SA_DLL int WINAPI apx5200saGetSyncSource(int nBoardIndex, int* pSyncSource);
APX5200SA_DLL int WINAPI apx5200saAoStart(int nBoardIndex, int nAoChannel);
APX5200SA_DLL int WINAPI apx5200saAoStop(int nBoardIndex, int nAoChannel);
APX5200SA_DLL int WINAPI apx5200saGetAoStatus(int nBoardIndex, int* pAoStatus, double* pAo1Value, double* pAo2Value);
APX5200SA_DLL int WINAPI apx5200saAoReleaseBuffer(int nBoardIndex, int nAoChannel);
APX5200SA_DLL int WINAPI apx5200saSetDiActiveLevel(int nBoardIndex, unsigned int uActiveLevel);
APX5200SA_DLL int WINAPI apx5200saGetDiActiveLevel(int nBoardIndex, unsigned int* pActiveLevel);
APX5200SA_DLL int WINAPI apx5200saGetDi(int nBoardIndex);
APX5200SA_DLL int WINAPI apx5200saSetDo(int nBoardIndex, unsigned int uDoData);
APX5200SA_DLL int WINAPI apx5200saGetDo(int nBoardIndex);
APX5200SA_DLL int WINAPI apx5200saSetBaseSetting(int nBoardIndex, char* pFilePath);
// ver.2.0.0
APX5200SA_DLL int WINAPI apx5200saSetCaptureInterval(int nBoardIndex, unsigned int nCaptureInterval);
APX5200SA_DLL int WINAPI apx5200saGetCaptureInterval(int nBoardIndex, unsigned int* pCaptureInterval);
APX5200SA_DLL int WINAPI apx5200saSetWindowAndDispersionEx(int nBoardIndex, double* pWindow, double* pTheta, int nFunctionIndex);
APX5200SA_DLL int WINAPI apx5200saGetWindowAndDispersionEx(int nBoardIndex, double* pWindow, double* pTheta, int nFunctionIndex);
APX5200SA_DLL int WINAPI apx5200saSetCaptureMode(int nBoardIndex, int nCaptureMode);
APX5200SA_DLL int WINAPI apx5200saGetCaptureMode(int nBoardIndex, int* pCaptureMode);
APX5200SA_DLL int WINAPI apx5200saGetFpgaConfiguration(int nBoardIndex, unsigned int* FpgaConfig);


//For Bscan
//Configures x-y position settings
APX5200SA_DLL int WINAPI apx5200saSetPositionSetting(int nBoardIndex, const HAD5200PositionSetting& posSetting);
APX5200SA_DLL int WINAPI apx5200saGetPositionSetting(int nBoardIndex, HAD5200PositionSetting& posSetting);

//Move to the specified position, 'dist' of argument
APX5200SA_DLL int WINAPI apx5200saMovePosition(int nBoardIndex, HAD5200_2D dist);
//Get current laser position.
APX5200SA_DLL int WINAPI apx5200saGetPosition(int nBoardIndex, HAD5200_2D &position);
//Configures bscan settings
APX5200SA_DLL int WINAPI apx5200saSetBscanSetting(int nBoardIndex, HAD5200BscanSetting &bScan);
APX5200SA_DLL int WINAPI apx5200saGetBscanSetting(int nBoardIndex, HAD5200BscanSetting &bScan);
//Start B scan
APX5200SA_DLL int WINAPI apx5200saStartBscan(int nBoardIndex);
//stop B scan
APX5200SA_DLL int WINAPI apx5200saStopBscan(int nBoardIndex);
//Bscan data is copied  to the specified address by 'bscan' argument.
APX5200SA_DLL int WINAPI apx5200saWaitBscanData(int nBoardIndex, unsigned int uTimeout,
	APX5200SA_DATA &status, float *bscan, unsigned int& size, unsigned int& depthSize);

//This function returns B scan data address to argument 'bscan'
//*The memory of 'bscan' is allocated by the driver
int WINAPI apx5200saWaitBscanData2(int nBoardIndex, unsigned int uTimeout,
                                   APX5200SA_DATA & status, float*& bscan, unsigned int& size, unsigned int& depthSize);

//Bscan data is copied  to the specified address by 'bscan' argument.(for labview)
APX5200SA_DLL int WINAPI apx5200saWaitBscanData3(int nBoardIndex, unsigned int uTimeout,
	APX5200SA_DATA &status, float *bscan, unsigned int& size, unsigned int& depthSize);

	
// Converts APX5200SA_DATA to get form apx5200saWaitSampling to B scan data array
APX5200SA_DLL int WINAPI apx5200saGetBscanData(int nBoardIndex,
                                               const APX5200SA_DATA &status, float *bscan, unsigned int& size, unsigned int& depthSize);
//Get the analog output array for B scan
//if doMEmAlloc is true, 'bScanValue's buffer is allocated by 'CoTaskMemAlloc'.
//So, please release 'bScanValues' by 'CoTaskMemFree'
APX5200SA_DLL int WINAPI apx5200saGetBscanAoValues(int nBoardIndex, HAD5200_2D* &bScanValues, size_t &size, bool doMemAlloc = false);

APX5200SA_DLL int WINAPI apx5200saSetCscanSetting(int nBoardIndex, HAD5200CscanSetting &cScan);

APX5200SA_DLL int WINAPI apx5200saGetCscanSetting(int nBoardIndex, HAD5200CscanSetting &cScan);

APX5200SA_DLL int WINAPI apx5200saStartCscan(int nBoardIndex); 


APX5200SA_DLL int WINAPI apx5200saStopCscan(int nBoardIndex); 
//Cscan line data is copied  to the specified address by 'cscanSegment' argument.
//line number is returned to segmentIndex.
APX5200SA_DLL int WINAPI apx5200saWaitCscanData(int nBoardIndex, unsigned int uTimeout,
	APX5200SA_DATA &status, float *cscanSegment, unsigned int& size, unsigned int& depthSize, unsigned int &segmentIndex);

//Store the C scan data address in 'cscanSegment' argument.
//buffer is allocated by the driver. If scan mode is round trip, returning way data is  is in reverse order
//line number is returned to segmentIndex.
APX5200SA_DLL int WINAPI apx5200saWaitCscanData2(int nBoardIndex, unsigned int uTimeout,
	APX5200SA_DATA &status, float *& cscanSegment, unsigned int& size, unsigned int& depthSize, unsigned int &segmentIndex);

//Set the custom scan positions
APX5200SA_DLL int WINAPI apx5200saSetCustomBscanSetting(int nBoardIndex, HAD5200BscanSetting &bScan,HAD5200_2D* customPositions,bool setBackward);

//Get the custom scan positions
APX5200SA_DLL int WINAPI apx5200saGetCustomBscanSetting(int nBoardIndex, HAD5200BscanSetting &bScan, HAD5200_2D* customPositions, bool &setBackward);

APX5200SA_DLL int WINAPI apx5200saGetBscanDataSize(int nBoardIndex, unsigned int &depthSize, unsigned int &pointNum);

APX5200SA_DLL int WINAPI apx5200saGetCscanDataSize(int nBoardIndex, unsigned int &depthSize, unsigned int &lineNumber, unsigned int &linePoints);


/**
 * \brief Gets the size of set scan data
 * \param nBoardIndex nBoardIndex Specifies board index
 * \param type 0: B scan, Other: C scan
 * \param offset Stores offset
 * \param total_scan_size Stores total scan size
 * \param scan_size Stores scan size
 */
void WINAPI apx5200saGetScanSize(int nBoardIndex, int type, unsigned* offset, unsigned* total_scan_size, unsigned* scan_size);

/**
 * \brief Sets resampling size and FFT size
 * \param nBoardIndex Specifies board index
 * \param nResamplingSize Specifies resampling size in multiples of 32
 * \param nFftSize Specifies FFT size as a power of 2
 * \return If successful, 0 is returned. Otherwise, an error code is returned.
 */
APX5200SA_DLL int WINAPI apx5200saSetResamplingSizeEx(int nBoardIndex, int nResamplingSize, int nFftSize);
/**
 * \brief Gets resampling size and FFT size
 * \param nBoardIndex Specifies board index
 * \param pResamplingSize Stores resampling size
 * \param pFftSize Stores FFT size
 * \return If successful, 0 is returned. Otherwise, an error code is returned.
 */
APX5200SA_DLL int WINAPI apx5200saGetResamplingSizeEx(int nBoardIndex, int* pResamplingSize, int* pFftSize);

/**
 * \brief Get FPGA configuration information
 * \param nBoardIndex Specifies board index
 * \param inf Stores FPGA configuration information
 * \return successful, 0 is returned. Otherwise, an error code is returned.
 */
APX5200SA_DLL int WINAPI apx5200saGetFpgaInfo(int nBoardIndex, HAD5200_FPGA_INF *inf);

/**
 * \brief Get the trace data of the B scan. Trace data will be output even if the size of the trace data is over or the scannable range is over.
 * \param nBoardIndex Specifies board index
 * \param bScan Specifies B scan setting
 * \param output_type 1:position values, 2: voltage values, others:output only data_size
 * \param datasize Stores data size
 * \param offset Stores offset
 * \param backword Stores backword
 * \param trace_data Stores array of the trace data, the size of the array is datasize. Check the required data size in advance
 * \return 
 */
APX5200SA_DLL int WINAPI apx5200saGetBscanTraceData(int nBoardIndex,const HAD5200BscanSetting* bScan,int output_type, int *data_size, int* offset, int* backword, HAD5200_2D* trace_data);

/**
 * \brief Get the trace data of the C-Scan. Trace data will be output even if the size of the trace data is over or the scannable range is over.
 * \param nBoardIndex Specifies board index
 * \param cScan Specifies C scan setting. If this function is successful, the value of TotalLinePointNumber and LineNum are set.
 * \param output_type output_type 1:position values, 2: voltage values, others:output only fast_axis_trace_size and slow_axis_trace_size.
 * \param fast_axis_trace_size Store the size of the fast axis trace data
 * \param slow_axis_trace_size Store the size of the slow axis trace data
 * \param offset Store the offset
 * \param fast_axis_trace Stores array of the fast axis trace data, the size of the array is fast_axis_trace_size. Check the required data size in advance and allocate the memory.
 * \param slow_axis_trace Stores array of the slow axis trace data, the size of the array is fast_axis_trace_size. Check the required data size in advance and allocate the memory.
 * \return If successful, 0 is returned. Otherwise, an error code is returned.
 */
APX5200SA_DLL int WINAPI apx5200saGetCscanTraceData(int nBoardIndex, HAD5200CscanSetting* cScan, int output_type, int* fast_axis_trace_size, int* slow_axis_trace_size, int* offset, float* fast_axis_trace, float* slow_axis_trace);

#ifdef __cplusplus
}
#endif

#endif